##############################################################################
#
# Copyright (c) 2006-2008 Kapil Thangavelu <kapil.foss@gmail.com>
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

from zope.interface import Interface, Attribute, directlyProvides
from zope.interface.common.mapping import IEnumerableMapping
from zope.app.container.interfaces import IContainer
from zope import schema

class TransmutationException( Exception ):
    """
    schema translation exception
    """

class IAlchemistTransmutation( Interface ):

    def transmute( schema, **kw ):
        """
        translates the schema and returns the translation.
        
        translations and kw are specific to the translation being performed.
        """

class IDatabaseEngine( Interface ):
    """
    configuration and access to pooled database connection
    """
    

class IEngineVocabularyUtility( Interface ):

    engines = schema.Iterable( title = u"RDB Engines",
                               description = u"Available RDB Engines")

class IDomainVocabularyUtility( Interface ):

    domain_classes = schema.Iterable( title=u"Domain Classes",
                                      description = u"Registered Domain Classes")

class IAlchemistContainer( IContainer ):
    """
    a domain record container
    """

    domain_class = schema.Choice(
        title = u"Domain Class",
        description = u"The Python Path of the Domain Class",
        required = True,
        vocabulary = "Alchemist Domain Classes"
        )
    
    domain_model = Attribute("domain_model", "The domain class")

    def query( **kw ):
        """
        return the specified children of the container
        """
        
    def batch( order_by=(), start=0, limit=20 ):
        """
        return a batch of contents with the given offset and size, and ordered
        by given listing of columns
        """

class ITableSchema( Interface ):
    """
    base interface for autogenerated schemas/interfaces derived
    from sqlalchemy table definitions
    """

class IAlchemistContent( ITableSchema ):
    """
    base interface for autogenerated schemas/interfaces derived
    from rdb definitions
    """                 
    
class ISQLAlchemyMetadata( Interface ):
    """ marker for sqlalchemy.BoundMetaData objects
    """

class ISchemaIntrospector( IEnumerableMapping ):
    """ a read dictionary interfaces to tables """

    def bind( metadata=None, engine=None ):
        """
        binds introspector to a particular bound metadata, if metadata is none, create a new
        metadata and bind to the passed in engine
        """

    def bindEngine( engine, schema_name=None):
        """
        bind the engine to the introspector, creates an internal bound metadata to the engine.
        """
        
    def bindMetadata( metadata ):
        """
        bind the introspector to the bound metadata, the metadata utilized will be the parent
        for any introspected tables returned.
        """
    metadata = Attribute("metadata", "Bound Metadata")

    information_schema = Attribute("information_schema",
                                   "the bound metadata containing table definitions for ansi information schema"
                                   )

class IIModelInterface( Interface ):
    """
    marker interface on generated table schema interfaces, ie. a marker for interfaces
    """

class IModelAnnotation( Interface ):
    """
    """
    def getDisplayColumns():
        """
        return the columns that should be displayed
        """

class IModelDescriptor( IEnumerableMapping ):
    """
    captures model behavior encapsulated in a set of fields, which are
    accessible via the enumerable mapping
    """
    
class IRelationChange( Interface ):
    """
    attached to modified events to allow for introspecting relation changes
    """
    #description = interface.Attribute(u"description")
    
class IModelDescriptorField( Interface ):

    modes = schema.ASCIILine( title=u"View Usage Modes for Field",
                              description=u"Pipe separated string of different modes.. add|edit|view|search|listing are all valid")

    view_widget = schema.Object(
        Interface,
        title=u"A Custom Widget Factory for Read Views",
        required = False
        )

    view_permission = schema.ASCIILine(
        title=u"Read Permission",
        description=u"If the user does not have this permission this field will not appear in read views",
        required = False
        )

    edit_widget = schema.Object(
        Interface,
        title=u"A Custom Widget Factory for Write Views",
        required = False,
        )

    edit_permission = schema.ASCIILine(
        title=u"Read Permission",
        description=u"If the user does not have this permission this field will not appear in write views",
        required = False
        )    

    add_widget = schema.Object(
        Interface,
        title=u"A Custom Widget Factory for Add Views",
        required = False
        )    

    search_widget = schema.ASCIILine(
        title=u"A Custom Search Widget Factory",
        required = False
        )

    listing_column = schema.Object(
        Interface,
        title=u"A Custom Column Widget for Listing Views",
        required = False        
        )
                                  
                                    
